package cn.yitun.chat.yitunservermanagecore.general.manage.system.service.impl;

import cn.yitun.chat.yituncommonutil.YitunMapUtil;
import cn.yitun.chat.yituncommonutil.YitunObjectUtil;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitunservercommonlib.constant.Constants;
import cn.yitun.chat.yitunservercommonlib.crud.yitun.CrudServiceImpl;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.RoleDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.RoleInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.RoleMenuInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.RoleVo;
import cn.yitun.chat.yitunserverimbase.dao.system.RoleDao;
import cn.yitun.chat.yitunserverimbase.dao.system.RoleMenuDao;
import cn.yitun.chat.yitunserverimbase.dao.system.UserRoleDao;
import cn.yitun.chat.yitunservermanagecore.general.manage.system.service.RoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;


/**
 * 
 * date 2018-07-12 11:15:01<br>
 * description
 * 
 * @author yitun<br>
 * @since
 */
@Service
@Transactional
public class RoleServiceImpl
		extends CrudServiceImpl<RoleDao,RoleDto, RoleInfo, RoleVo>
		implements RoleService {

	@Resource
	RoleMenuDao roleMenuDAO;
	@Resource
	UserRoleDao userRoleDAO;

	@Transactional
	@Override
	public int save(RoleDto role) {
		role.setId(role.getId());
		int count = dao.save(role);
		if (count > 0 ){
			List<Long> menuIds = role.getMenuIds();
			Long roleId = role.getId();
			List<RoleMenuInfo> rms = new ArrayList<>();
			saveRoleMenu(menuIds, rms, roleId);
		}
		return count;
	}

	@Override
	@Transactional
	public int update(RoleDto role) {
		int r = dao.update(role);
		if (r > 0){
			List<Long> menuIds = role.getMenuIds();
			Long roleId = role.getId();
			roleMenuDAO.deleteByRoleId(roleId);
			List<RoleMenuInfo> rms = new ArrayList<>();
			saveRoleMenu(menuIds, rms, roleId);
		}
		return r;
	}

	@Transactional
	public void saveRoleMenu(List<Long> menuIds, List<RoleMenuInfo> rms, Long roleId) {
		for (Long menuId : menuIds) {
			RoleMenuInfo rmDo = new RoleMenuInfo();
			rmDo.setRoleId(roleId);
			rmDo.setMenuId(menuId);
			rms.add(rmDo);
		}
		if (rms.size() > 0) {
			roleMenuDAO.batchSave(rms);
		}
	}
	@Override
	public RoleInfo getRole(Long id) {
		return dao.get(id);
	}
	@Override
	public void addOrUpdate(RoleDto role, List<Long> menuIds) {
		if (null == role.getId()) {
			dao.save(role);
		} else {
			dao.update(role);
		}
		Long roleId = role.getId();
		addOrUpdate(roleId, menuIds);
	}
	@Override
	public void addOrUpdate(Long roleId, List<Long> menuIds) {
		List<RoleMenuInfo> rmList = roleMenuDAO.getRoleMenuListByRoleId(roleId);

		List<RoleMenuInfo> deleteList = new ArrayList<>();
		Map<Long, RoleMenuInfo> map = new HashMap<>();
		for (RoleMenuInfo rm : rmList) {
			if (map.containsKey(rm.getMenuId())) {
				deleteList.add(rm);
			}
			map.put(rm.getMenuId(), rm);
		}

		List<RoleMenuInfo> addList = new ArrayList<>();
		if (null != menuIds) {
			for (Long menuId : menuIds) {
				RoleMenuInfo rm = map.remove(menuId);
				if (null == rm) {
					rm = new RoleMenuInfo();
					rm.setRoleId(roleId);
					rm.setMenuId(menuId);
					addList.add(rm);
				}
			}
		}
		deleteList.addAll(map.values());
		if (!addList.isEmpty()) {
			for (RoleMenuInfo rm : addList) {
				roleMenuDAO.save(rm);
			}
		}
		if (!deleteList.isEmpty()) {
			for (RoleMenuInfo rm : deleteList) {
				roleMenuDAO.remove(rm.getId());
			}
		}
	}
	@Override
	public void delete(Long id) {
		dao.remove(id);
		roleMenuDAO.deleteByRoleId(id);
		userRoleDAO.deleteByRoleId(id);
	}
	@Override
	public List<RoleVo> queryList(RoleDto roleQuery) {
		List<RoleVo> roleList = dao.listVO(YitunMapUtil.java2Map(roleQuery, false));
		return roleList;
	}
	@Override
	public List<RoleVo> listVo(RoleDto roleDto) {
		List<RoleVo> roleList = dao.listVO(YitunMapUtil.java2Map(roleDto, false));
		return roleList;
	}
	@Override
	public RoleVo getVo(Long id) {
		return dao.getVO(id);
	}

	/**
	 * 获取用户角色id
	 * @param userId
	 * @return
	 */
	@Override
	public List<Long> roleIdsByUserId(Long userId) {
		return dao.roleIdsByUserId(userId);
	}

	/**
	 * 校验角色名称是否唯一
	 * @param role 角色信息
	 * @return 结果
	 */
	@Override
	public Boolean checkRoleNameUnique(RoleInfo role) {
		if(YitunStringUtil.isEmpty(role.getRoleName()))
			return Constants.ROLE_NAME_NOT_UNIQUE;
		Long roleId = YitunObjectUtil.isEmpty(role.getId()) ? -1 : role.getId();
		RoleInfo info = dao.checkRoleNameUnique(role);
		if (YitunObjectUtil.isNotEmpty(info) && !info.getId().equals(roleId)) {
			return Constants.ROLE_NAME_NOT_UNIQUE;
		}
		return !Constants.ROLE_NAME_NOT_UNIQUE;
	}

	/**
	 * 校验角色权限是否唯一
	 *
	 * @param role 角色信息
	 * @return 结果
	 */
	@Override
	public Boolean checkRoleSignUnique(RoleInfo role) {
		if(YitunStringUtil.isEmpty(role.getRoleSign()))
			return Constants.ROLE_NAME_NOT_UNIQUE;
		Long roleId = YitunObjectUtil.isEmpty(role.getId()) ? -1 : role.getId();
		RoleInfo info = dao.checkRoleSignUnique(role);
		if (YitunObjectUtil.isNotEmpty(info) && !info.getId().equals(roleId)) {
			return Constants.ROLE_NAME_NOT_UNIQUE;
		}
		return !Constants.ROLE_NAME_NOT_UNIQUE;
	}

	/**
	 * 根据用户ID查询权限
	 *
	 * @param userId 用户ID
	 * @return 权限列表
	 */
	@Override
	public Set<String> selectRoleKeys(Long userId) {
		List<RoleInfo> perms = listByUserId(userId);
		Set<String> permsSet = new HashSet<>();
		for (RoleInfo perm : perms) {
			if (YitunStringUtil.isNotNull(perm)) {
				permsSet.addAll(Arrays.asList(perm.getRoleSign().trim().split(",")));
			}
		}
		return permsSet;
	}

	@Override
	public List<RoleInfo> listByUserId(Long userId) {
		return dao.listByUserId(userId) ;
	}
}
